package com.um.jdy.baofu.api.impl;

import cn.hutool.core.util.NumberUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.um.jdy.baofu.api.BaoFuAccountService;
import com.um.jdy.baofu.config.BFConfig;
import com.um.jdy.baofu.entity.account.*;
import com.um.jdy.baofu.http.HttpUtil;
import com.um.jdy.baofu.rsa.RsaCodingUtil;
import com.um.jdy.baofu.utils.SecurityUtil;
import com.um.springboot.starter.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class BaoFuAccountServiceImpl implements BaoFuAccountService {
    @Autowired
    private BFConfig bFConfig;
    @Override
    public JSONObject BCT3_1002_001_01(BCT3100200101Entity bodyInfo) {
        String serviceTp = "BCT3-1002-001-01";
        ContentBodyEntity<BCT3100200101Entity> bodycontent = new ContentBodyEntity<BCT3100200101Entity>();
        bodyInfo.setNoticeUrl(bFConfig.getAccountNoticeUrl());
        bodyInfo.setVersion("1.0.0");
        //BodyInfo.setAccType(2);//账户类型:1-个人,2-企业/个体
        bodyInfo.setBusinessType("BCT3");
        bodycontent.setBody(bodyInfo);

        ContentBodyEntity<RsultBodyEntity> contenBe =requestProcessing(bodycontent,serviceTp,1);

        JSONObject jsonObject = JSON.parseArray(JSON.toJSONString(contenBe.getBody().getResult())).getJSONObject(0);
        if(jsonObject.getInteger("state") == 0 || jsonObject.getInteger("state") == 1){
            throw new ServiceException("开户失败："+jsonObject.getString("errorMsg"));
        }
        return jsonObject;
    }

    @Override
    public ContentBodyEntity BCT3_5001_001_01(ValuesActionEntity vsae) {
        //接口名 分账加值
        String serviceTp = "BCT3-5001-001-01";
        String memberId = bFConfig.getMemberid();//商户号
        String terminalId = bFConfig.getTerminalid();//终端号

        //数据去重
        if(vsae.getAcctInfo() != null && vsae.getAcctInfo().size() > 0){
            vsae.setAcctInfo(merge(vsae.getAcctInfo()));
        }

        String reqTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//报文发送日期时间
        vsae.setVersion("1.0.0");
        vsae.setReqTime(reqTime);
        vsae.setPlatformNo(memberId);
        //默认分账好余额
        vsae.setAccountType("BALANCE");
        ContentBodyEntity<ValuesActionEntity> bodycontent = new ContentBodyEntity<>();
        bodycontent.setBody(vsae);
        //bodycontent.setHeader(headerinfo);
        ContentBodyEntity<RsultBodyEntity> contenBe = requestProcessing(bodycontent,serviceTp,1);
        if(contenBe.getBody() == null || contenBe.getBody().getState() == 0){
            throw new ServiceException("分账加值失败"+contenBe.getBody().getErrorMsg());
        }
        return contenBe;
    }

    @Override
    public ContentBodyEntity BCT3_5002_001_01(ValuesActionEntity vsae) {
        //接口名 分账加值
        String serviceTp = "BCT3-5002-001-01";
        String memberId = bFConfig.getMemberid();//商户号
        String terminalId = bFConfig.getTerminalid();//终端号
        //数据去重
        if(vsae.getAcctInfo() != null && vsae.getAcctInfo().size() > 0){
            vsae.setAcctInfo(merge(vsae.getAcctInfo()));
        }
        String reqTime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());//报文发送日期时间
        vsae.setVersion("1.0.0");
        vsae.setReqTime(reqTime);
        vsae.setPlatformNo(memberId);
        //默认分账好余额
        vsae.setAccountType("BALANCE");
        ContentBodyEntity<ValuesActionEntity> bodycontent = new ContentBodyEntity<>();
        bodycontent.setBody(vsae);
        //bodycontent.setHeader(headerinfo);
        ContentBodyEntity<RsultBodyEntity> contenBe = requestProcessing(bodycontent,serviceTp,1);
        if(contenBe.getBody() == null || contenBe.getBody().getState() == 0){
            throw new ServiceException("分账减值值失败"+contenBe.getBody().getErrorMsg());
        }
        return contenBe;
    }

    @Override
    public RsultTransferEntity BCT3_3002_001_01(TransAccountEntity tracce) {
        //接口名 提现
        String serviceTp = "BCT3-3002-001-01";
        String memberId = bFConfig.getMemberid();//商户号
        tracce.setVersion("1.0.0");
        tracce.setReturnUrl(bFConfig.getAccountNoticeUrl());
        //默认自己承担手续费
        //tracce.setFeeMemberId(tracce.getContractNo());
        ContentBodyEntity<TransAccountEntity> bodycontent = new ContentBodyEntity<>();
        bodycontent.setBody(tracce);
        ContentBodyEntity<RsultTransferEntity> contenBe = requestProcessing(bodycontent,serviceTp,3);
        if(contenBe.getBody() == null || !"1".equals(contenBe.getBody().getState())){
            throw new ServiceException("提现受理失败"+contenBe.getBody().getTransRemark());
        }
        log.info("账号："+tracce.getContractNo()+" 申请提现，金额"+tracce.getDealAmount());
        return contenBe.getBody();
    }

    @Override
    public RsultBalanceEntity BCT3_2001_001_01(String contractNo, Integer accType) {
        //接口名 提现
        String serviceTp = "BCT3-2001-001-01";
        BCT3PublicPostEntity querybody = new BCT3PublicPostEntity();
        querybody.setVersion("1.0.0");
        querybody.setAccType(accType);
        querybody.setContractNo(contractNo);

        ContentBodyEntity<BCT3PublicPostEntity> bodycontent = new ContentBodyEntity<>();
        bodycontent.setBody(querybody);
        ContentBodyEntity<RsultBalanceEntity> contenBe = requestProcessing(bodycontent,serviceTp,2);
        if(contenBe.getBody() == null || contenBe.getBody().getRetCode() !=1){
            throw new ServiceException("查询账户信息失败"+contenBe.getBody().getErrorMsg());
        }
        return contenBe.getBody();
    }

    /**
     *
     * @param entity
     * @param serviceTp
     * @param type 1 RsultBodyEntity
     *       type 2 RsultBalanceEntity
     *             type 3 RsultTransferEntity
     * @return
     */
    public ContentBodyEntity requestProcessing(ContentBodyEntity entity,String serviceTp,int type){
        String memberId = bFConfig.getMemberid();//商户号
        String terminalId = bFConfig.getTerminalid();//终端号
        try{
            HeaderEntity headerinfo = new HeaderEntity();
            headerinfo.setMemberId(memberId);
            headerinfo.setTerminalId(terminalId);
            headerinfo.setServiceTp(serviceTp);
            headerinfo.setVerifyType("1");
            entity.setHeader(headerinfo);

            PostParmEntity postparm = new PostParmEntity();
            postparm.setMemberId(memberId);
            postparm.setTerminalId(terminalId);

            //加密数据
            String ContentStr = JSON.toJSONString(entity);
            log.info("JSON序列号："+ContentStr);
            String base64str = SecurityUtil.Base64Encode(ContentStr);
            String enContent = RsaCodingUtil.encryptByPriPfxFile(base64str, bFConfig.getPripath(),bFConfig.getPfxpwd());
            postparm.setContent(enContent);

            //发送请求
            String PostString  = HttpUtil.RequestForm(bFConfig.getAccountUrl()+serviceTp+"/transReq.do", postparm);
            //String PostString  = HttpUtil.RequestForm("https://vgw.baofoo.com/union-gw/api/"+ServiceTp+"/transReq.do", postparm);
            log.info("返回参数："+PostString);
            if(PostString.isEmpty()) throw new Exception("请求返回异常");

            if(PostString.isEmpty()) throw new ServiceException("请求返回异常");

            if(PostString.contains("header")){
                //调用失败
                ResultErrorEntity resulterror = JSON.parseObject(PostString,ResultErrorEntity.class);
                log.info("结果："+resulterror.getHeader().getSysRespCode()+","+resulterror.getHeader().getSysRespDesc());
                throw new ServiceException("请求失败："+resulterror.getHeader().getSysRespDesc());
            }else{
                //成功
                String DePostString = RsaCodingUtil.decryptByPubCerFile(PostString, bFConfig.getCerpath());
                if(DePostString.isEmpty()) throw new ServiceException("解密空值，请检查证书是否正常");
                DePostString = SecurityUtil.Base64Decode(DePostString);
                log.info("返回明文："+DePostString);
                if(DePostString.contains("header")){
                    ContentBodyEntity<RsultBodyEntity> contenBe = JSON.parseObject(DePostString,new TypeReference<ContentBodyEntity<RsultBodyEntity>>(){});
                    if(contenBe.getHeader().getSysRespCode().equals("S_0000")){
                        log.info("业务层结果："+JSON.toJSONString(contenBe.getBody()));
                        if(contenBe.getBody().getRetCode() == 1){
                            //log.info("结果："+JSON.toJSONString(contenBe.getBody().getResult()));
                            //JSONObject jsonObject = JSON.parseArray(JSON.toJSONString(contenBe.getBody().getResult())).getJSONObject(0);
//                            if(jsonObject.getInteger("state") == 0 || jsonObject.getInteger("state") == 1){
//                                throw new ServiceException("开户失败："+jsonObject.getString("errorMsg"));
//                            }
                            if(type==1){
                                return JSON.parseObject(DePostString,new TypeReference<ContentBodyEntity<RsultBodyEntity>>(){});
                            }else if(type==2){
                                return JSON.parseObject(DePostString,new TypeReference<ContentBodyEntity<RsultBalanceEntity>>(){});
                            }else if(type==3){
                                return JSON.parseObject(DePostString,new TypeReference<ContentBodyEntity<RsultTransferEntity>>(){});
                            }else {
                                throw new ServiceException("未知类型");
                            }
                            //return contenBe;
                            /***
                             * 略。。。。
                             */
                        }else{
                            log.info("结果："+contenBe.getBody().getRetCode()+","+contenBe.getBody().getErrorCode()+","+contenBe.getBody().getErrorMsg());
                            throw new ServiceException("操作失败："+contenBe.getBody().getErrorMsg());
                        }
                    }else{
                        log.info("结果："+contenBe.getHeader().getSysRespCode()+","+contenBe.getHeader().getSysRespDesc());
                        throw new ServiceException("报文异常");
                    }
                }else{
                    throw new ServiceException("报文异常");
                }
            }
        }catch (Exception ex){
            log.error(ex.getMessage());
            throw new ServiceException(ex.getMessage());
        }

    }


    /**
     * 将id进行合并nums, sums 相加道回合并后的集合使用Java8的流进行处理
     */
    public static List<ValuesAcctInfoEntity>  merge(List<ValuesAcctInfoEntity> list) {
        DecimalFormat df = new DecimalFormat("0.00");
        List<ValuesAcctInfoEntity> result = list.stream()
                // 表示id为key， 接着如果有重复的，那么从BillsNums对象o1与o2中筛选出一个，这里选择o1，
                // 并把id重复，需要将nums和sums与o1进行合并的o2, 赋值给o1，最后返回o1
                .collect(Collectors.toMap(ValuesAcctInfoEntity::getContractNo, a -> a, (o1, o2)-> {
                    o1.setTransAmount(df.format(Double.parseDouble(o1.getTransAmount())+Double.parseDouble(o2.getTransAmount())));
                    return o1;
                })).values().stream().collect(Collectors.toList());
        return result ;
    }

    public static void main(String[] args) {
        List<ValuesAcctInfoEntity> listvaie = new ArrayList<ValuesAcctInfoEntity>();
        ValuesAcctInfoEntity vaie1 = new ValuesAcctInfoEntity();
        vaie1.setContractNo("CM610000000000174898");
        vaie1.setTransAmount("20.001");
        ValuesAcctInfoEntity vaie2 = new ValuesAcctInfoEntity();
        vaie2.setContractNo("CM610000000000174898");
        vaie2.setTransAmount("10.00567");
        listvaie.add(vaie1);
        listvaie.add(vaie2);
        listvaie= merge(listvaie);
        listvaie.forEach(System.out::println);
    }

}
